package cn.akwangl.spring.bean.definition;

import cn.akwangl.spring.ioc.enums.RoleLeve;
import cn.akwangl.spring.ioc.model.SuperUser;
import cn.akwangl.spring.ioc.model.User;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;

/**
 * {@link BeanDefinition} 使用Demo
 *
 * @author youyongkun
 * @date 2021/6/29 14:46
 */
public class BeanDefinitionDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(BeanDefinitionDemo.class);
        applicationContext.registerBeanDefinition("user", carteBeanDefinition(User.class));
        applicationContext.refresh();


        SuperUser superUser = applicationContext.getBean("superUser", SuperUser.class);
        System.out.println(superUser);

        User user = applicationContext.getBean("user", User.class);
        System.out.println(user);
    }

    @Bean
    public SuperUser superUser() {
        SuperUser superUser = new SuperUser();
        superUser.setId("2");
        superUser.setName("超级用户");
        superUser.setRole(RoleLeve.ADMIN);
        return superUser;
    }

    /**
     * 创建{@link BeanDefinitionBuilder} BeanDefinition
     * BeanDefinition 是SpringBean 的元信息配置类,其中可以设置如下
     * 1. 设置懒加载
     * 2. 设置作用域 Scope
     * 3. 设置构造Constructor arguments
     * ...
     *
     * @param beanClass Clazz类型
     * @return BeanDefinition
     * @author youyongkun
     * @date 2021/6/29 15:52
     */
    public static BeanDefinition carteBeanDefinition(Class<?> beanClass) {
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(beanClass).getBeanDefinition();

        // 如果superUser这个bean不存在容器中则会抛出一下异常
        // Error creating bean with name 'user': 'user' depends on missing bean 'superUser';
        // nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
        // No bean named 'superUser' available
        beanDefinition.setDependsOn("superUser");

        // 指定初始化方法
        beanDefinition.setInitMethodName("init");
        // 设置懒加载
        beanDefinition.setLazyInit(true);
        return beanDefinition;
    }


}
